package csel.controller.factories;

import csel.controller.commands.*;
import csel.model.GameCommand;
import csel.model.Model;
import csel.view.AreaViewport;
import csel.view.Splasher;
import csel.view.StatusViewport;

/**
 * Reasons for Existence: implements a factory method which returns an object 
 * of type GameCommand which can be used by the model
 * Team Members Responsible
 * Implementation: Nik, Tait
 * Testing: Nik, Tait 
 * 
 * @author Nikolas Wolfe
 */
public class ModelCommandFactory implements CommandFactory
{
	// Instance variables
	private Model model; 
	private StatusViewport statusViewport;
	private AreaViewport areaViewport;
	private Splasher splashViewport;
	private CommandFactory currFactory;
	
	//constuctor
	public ModelCommandFactory(
			Model model,
			Splasher splashViewport,
			AreaViewport areaViewport,
			StatusViewport statusViewport )
	{
		this.model = model;
		this.splashViewport = splashViewport;
		this.areaViewport = areaViewport;
		this.statusViewport = statusViewport;
		
	}
	
	// public interface 
	public GameCommand createGameCommand()
	{
		return currFactory.createGameCommand();
	}
	
	// This is a move command for the model
	public void newMoveCommandFactory( Character c )
	{
		currFactory = new MoveCommandFactory( c );
	}
	
	// This is a stop command for the model
	public void newStopCommandFactory()
	{
		currFactory = new StopCommandFactory();
	}

	//This is a quit command for the model?
	public void newQuitCommandFactory()
	{
		currFactory = new QuitCommandFactory();
	}
	
	//This is a drop item command for the model
	public void newDropCommandFactory()
	{
		currFactory = new DropCommandFactory();
	}

	//This is a use item command for the model
	public void newUseCommandFactory()
	{
		currFactory = new UseCommandFactory();
	}

	//This is an equip item command for the model
	public void newEquipCommandFactory()
	{
		currFactory = new EquipCommandFactory();
	}

	//This is an Unequip Item command for the model
	public void newUnequipCommandFactory()
	{
		currFactory = new UnequipCommandFactory();
	}

	//This is a save command for the model
	public void newSaveCommandFactory()
	{
		currFactory = new SaveCommandFactory();
	}

	//This is a load command for the model
	public void newLoadCommandFactory()
	{
		currFactory = new LoadCommandFactory();
	}
	
	//This is a new game command for the model
	public void newNewCommandFactory()
	{
		currFactory = new NewCommandFactory();
	}
	/*
	 * ---------------------
	 * Command Sub-Factories
	 * ---------------------
	 */
	
	// Move Command Factory
	private class MoveCommandFactory implements CommandFactory
	{
		// value for the move
		private final GameCommand gameCommand;
		
		public MoveCommandFactory( Character character )
		{
			// set the parameter for the move
			this.gameCommand = new MoveCommand( character, model );
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// Stop Command Factory
	private class StopCommandFactory implements CommandFactory
	{
		// final instance, created on instantiation
		private final GameCommand stopCommand = new StopCommand( model );
		
		public GameCommand createGameCommand()
		{
			return stopCommand;
		}
	}	
	
	//Quit Command Factory
	private class QuitCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;
		
		public QuitCommandFactory()
		{
			this.gameCommand = new QuitCommand( model, splashViewport, statusViewport, areaViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// Drop Command Factory
	private class DropCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;
		
		public DropCommandFactory()
		{
			this.gameCommand = new DropCommand( model, statusViewport );
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// Use Command Factory
	private class UseCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;
		
		public UseCommandFactory()
		{
			this.gameCommand = new UseCommand( model, statusViewport );
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}

	// Equip Command Factory
	private class EquipCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;

		public EquipCommandFactory()
		{
			this.gameCommand = new EquipCommand(model, statusViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}

	// Unequip Command Factory
	private class UnequipCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;

		public UnequipCommandFactory()
		{
			this.gameCommand = new UnequipCommand(model, statusViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// Save Command Factory
	private class SaveCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;

		public SaveCommandFactory()
		{
			this.gameCommand = new SaveCommand(model, statusViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// Load Command Factory
	private class LoadCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;

		public LoadCommandFactory()
		{
			this.gameCommand = new LoadCommand(model, statusViewport, splashViewport, areaViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
	
	// New Game Command Factory
	private class NewCommandFactory implements CommandFactory
	{
		private final GameCommand gameCommand;

		public NewCommandFactory()
		{
			this.gameCommand = new NewCommand(model, statusViewport, splashViewport, areaViewport);
		}

		public GameCommand createGameCommand()
		{
			return this.gameCommand;
		}
	}
}
